package com.shopping.filters;

import com.alibaba.fastjson2.JSONObject;
import com.shopping.commons.CurUserInfo;
import com.shopping.commons.Result;
import com.shopping.utils.JWTUtils;
import com.shopping.utils.RSAUtils;
import io.jsonwebtoken.Jwts;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationConverter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.*;

/**
 * 自定义过滤器
 */
public class ShoppingBasicAuthenticationFilter extends BasicAuthenticationFilter {
    public ShoppingBasicAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String requestUri = request.getRequestURI().substring(1);
        System.out.println(requestUri);
        try {
            //获得请求路径

            //让无需认证请求直接通过
            if (requestUri.matches("^book/.+|register")) {
//                System.out.println("匹配成功");
                chain.doFilter(request, response);//交给下一个过滤器
                return;
            }
            //获得请求头的Authorization的属性里面包含前端的Token
            String token = request.getHeader("Authorization");
            //是否携带Token
            if (token == null || token.equals("")) {
                if (!requestUri.equals("validateToken")) {
                    response.setContentType("application/json;charset=utf-8");
                    //401:未认证
                    response.getWriter().println(JSONObject.toJSONString(Result.fail(401, "请登录后访问")));
                    return;
                }
            }
            //解析Token
            //获取公钥
            PublicKey publicKey = RSAUtils.getPublicKey("D:\\Java源码\\demo\\shopping\\myshopping-project-server\\src\\main\\resources\\Keys\\key.public");
//        Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token);
            //解析负载数据
            Map<String, Object> payloadMap = JWTUtils.getPayLoadFromToken(token, publicKey, Map.class);//解析负载数据
//            System.out.println(curUserInfo);
            //负载信息获得curUserInfo，返回一个LinkedHashMap集合
            LinkedHashMap curUserInfoMap = (LinkedHashMap) payloadMap.get("curUserInfo");
            CurUserInfo curUserInfo = new CurUserInfo();
            curUserInfo.setUser_name((String) curUserInfoMap.get("user_name"));
            curUserInfo.setUser_id((Integer) curUserInfoMap.get("user_id"));
            request.getSession().setAttribute("curUserInfo", curUserInfo);
            //负载信息里的认证信息
            List<Map<String, Object>> authorities = (List<Map<String, Object>>) payloadMap.get("authorities");
            System.out.println(authorities);
            List<SimpleGrantedAuthority> authorityList = new ArrayList<>();
            for (Map<String, Object> map : authorities) {
                String authorStr = (String) map.get("authority");
                SimpleGrantedAuthority authority = new SimpleGrantedAuthority(authorStr);
                //将authority添加到List集合
                authorityList.add(authority);
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(curUserInfo, null, authorityList);
            //将认证信息添加到SecurityContextHolder
            SecurityContext context = SecurityContextHolder.createEmptyContext();
            context.setAuthentication(authentication);
            SecurityContextHolder.setContext(context);

            //验证Token是否有效，如果有效直接返回成功即可
            if (requestUri.equals("validateToken")) {
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().println(JSONObject.toJSONString(Result.success()));
                return;
            }

            chain.doFilter(request, response);
        } catch (Exception e) {
            e.printStackTrace();
            //验证Token是否有效，如果有效直接返回成功即可
            if (requestUri.equals("validateToken")) {
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().println(JSONObject.toJSONString(Result.fail(520)));
                return;
            }
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().println(JSONObject.toJSONString(Result.fail(401, "请登录后访问")));
        }
    }
}
